#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
飞机大战 v0.5
画面效果完成，没有音乐
'''
import turtle
from turtle import *
import random
import time


def drawMyPlane(x, y):
    """
    给出一个飞机底部中心的坐标，画一个三角形的飞机
    :param x: 坐标X
    :param y: 坐标Y
    :return:
    """
    plane_width = 20
    turtle.penup()
    turtle.setposition(x - plane_width / 2, y)
    pencolor("black")
    pendown()
    turtle.setposition(x + plane_width / 2, y)
    turtle.setposition(x, y + plane_width)
    turtle.setposition(x - plane_width / 2, y)
    penup()


def drawEnemyPlane(x, y):
    """
    在给定坐标为敌机底部的中间，画一个敌机，
    :param x:
    :param y:
    :return:
    """
    plane_width = 20
    turtle.penup()
    turtle.setposition(x - plane_width / 2, y)
    pencolor("black")
    fillcolor("black")
    pendown()
    begin_fill()
    turtle.setposition(x + plane_width / 2, y)
    turtle.setposition(x, y - plane_width)
    turtle.setposition(x - plane_width / 2, y)
    end_fill()
    penup()


def enemyPlaneMove():
    """
    敌机的移动
    :return:
    """
    global enemy_planes
    for enemy_plane in enemy_planes:
        enemy_plane_x = enemy_plane[0]
        enemy_plane_y = enemy_plane[1]
        drawEnemyPlane(enemy_plane_x, enemy_plane_y)
        enemy_plane[1] = enemy_plane_y - 5


def genEnemyPlane():
    """
    判断是否生成新敌机，如果可以，生成新敌机的新坐标
    :return:
    """
    global enemy_planes
    if len(enemy_planes) > 10:
        ''' 敌人太多，不生成 '''
        return

    gen_flag = random.random()
    gen_x = 0
    if gen_flag < 0.5:
        return
    else:
        gen_x = random.randint(-300, 300)

    for enemy_plane in enemy_planes:
        ''' 敌人飞机间水平与垂直距离太近，不生成 '''
        if (300 - enemy_plane[1]) < 50:
            return
        if abs(gen_x - enemy_plane[1]) < 50:
            return
    enemy_planes.append([gen_x, 300])


def enemyPlaneRemove():
    """
    如果飞机飞出屏幕，从飞机坐标队列中移除飞机
    :return:
    """
    global enemy_planes
    for enemy_plane in enemy_planes:
        enemy_plane_x = enemy_plane[0]
        enemy_plane_y = enemy_plane[1]
        if (enemy_plane_x > 300) or \
                (enemy_plane_x < -300) or \
                (enemy_plane_y > 300) or \
                (enemy_plane_y < -300):
            enemy_planes.remove(enemy_plane)


def hitEnemy():
    """
    判断是否有被击中的敌机
    :return:
    """
    global bullets, enemy_planes, score
    plane_width = 20
    ret_bullets = [];
    ret_enemy_planes = [];
    for bullet in bullets:
        for enemy_plane in enemy_planes:
            x_dis = abs(bullet[0] - enemy_plane[0])
            y_dis = abs(bullet[1] - enemy_plane[1])
            if (x_dis < plane_width) and (y_dis < plane_width):
                ret_bullets.append(bullet)
                ret_enemy_planes.append(enemy_plane)
                score = score + 10
    return ret_bullets, ret_enemy_planes


def removeHitEnemy(hit_bullets, hit_enemy_planes):
    """
    将被击中的敌机和子弹从屏幕移除
    :param hit_bullets:
    :param hit_enemy_planes:
    :return:
    """
    global enemy_planes, bullets
    for hit_enemy_plane in hit_enemy_planes:
        # print(hit_enemy_plane[0], hit_enemy_plane[1])
        if (enemy_planes.index(hit_enemy_plane)) >= 0:
            enemy_planes.remove(hit_enemy_plane)
    for hit_bullet in hit_bullets:
        if (bullets.index(hit_bullet)) >= 0:
            bullets.remove(hit_bullet)
            penup()
            setposition(hit_bullet[0], hit_bullet[1] - 10)
            pendown()
            begin_fill()
            fillcolor("red")
            circle(20)
            end_fill()
            time.sleep(0.02)


def planeCollision():
    """
    飞机碰撞检测，检测我方飞机与敌方飞机的碰撞
    :return:
    """
    plane_width = 20
    global enemy_planes, plane_x, plane_y
    for enemy_plane in enemy_planes:
        enemy_plane_x = enemy_plane[0]
        enemy_plane_y = enemy_plane[1]
        if (abs(enemy_plane_x - plane_x) < plane_width) and \
                (abs(enemy_plane_y - plane_y) < plane_width):

            return True
    return False


def drawFlyMile():
    """
    在屏幕上显示飞行里程
    :return:
    """
    global fly_mile, score
    fly_mile = fly_mile + 5
    penup()
    setposition(-300, 300)
    pencolor("black")
    pendown()
    write_str = "000000000" + str(fly_mile)
    # write_str = "飞行里程: " + write_str[-9:] + " 米                                                                            分数：" + str(score)
    write_str = "飞行里程: " + write_str[-9:] + " 米"
    write_str = write_str + "                                                                            分数：" \
                + str(score)
    write(write_str, font=("Arial", 16))


def bulletsMove():
    """
    子弹飞
    :return:
    """
    for bullet in bullets:
        bullet[1] = bullet[1] + 5


def bulletsRemove():
    """
    子弹出屏幕后移除
    :return:
    """
    global bullets
    for bullet in bullets:
        bullet_x = bullet[0]
        bullet_y = bullet[1]
        if (bullet_x > 300) or \
                (bullet_x < -300) or \
                (bullet_y > 300) or \
                (bullet_y < -300):
            bullets.remove(bullet)


def drawBullets():
    """
    画子弹
    :return:
    """
    global bullets

    for bullet in bullets:
        bullet_x = bullet[0]
        bullet_y = bullet[1]
        penup()
        setposition(bullet_x, bullet_y)
        pencolor("black")
        pendown()
        setposition(bullet_x, bullet_y - 5)
        penup()


def tick():
    """
    屏幕刷新过程
    :return:
    """
    global is_run
    try:
        hideturtle()
        tracer(0)
        enemyPlaneRemove()
        genEnemyPlane()
        turtle.clear()
        drawMyPlane(plane_x, plane_y)
        bulletsMove()
        drawBullets()
        enemyPlaneMove()
        hit_bullets, hit_enemy_planes = hitEnemy()
        removeHitEnemy(hit_bullets, hit_enemy_planes)
        drawFlyMile()

        if planeCollision():
            is_run = False

            penup()
            setposition(plane_x, plane_y - 10)
            pendown()
            begin_fill()
            fillcolor("red")
            circle(20)
            end_fill()

            # 碰撞后，显示"按空格重新开始"
            penup()
            setposition(-90, 0)
            pencolor("red")
            pendown()
            write("按空格键重新开始！", font=("Arial", 24))
            turtle.update()
            return
        else:
            turtle.update()
            ontimer(tick, 50)
    except Terminator:
        pass  # turtledemo user pressed STOP


def keyLeft():
    """
    按左键，飞机向左
    :return:
    """
    global plane_x
    if plane_x >= -290:
        plane_x = plane_x - 10


def keyRight():
    """
    按右键，飞机向右
    :return:
    """
    global plane_x
    if plane_x <= 290:
        plane_x = plane_x + 10


def keySpace():
    """
    按空格键发射炮弹
    :return:
    """
    global bullets, plane_x, plane_y, score, fly_mile, enemy_planes, is_run
    if is_run:
        bullet = [plane_x, plane_y + 20]
        bullets.append(bullet)
    else:
        score = 0
        plane_x = 0
        plane_y = -300
        bullets = []
        fly_mile = 0
        enemy_planes = []
        is_run = True
        tick()


plane_x = 0
plane_y = -300
is_run = True
enemy_planes = []
bullets = []
fly_mile = 0
score = 0;

if __name__ == "__main__":
    turtle.screensize(600, 600)
    turtle.listen()
    turtle.onkeypress(keyLeft, "Left")
    turtle.onkeypress(keyRight, "Right")
    turtle.onkeypress(keySpace, "space");
    tick()
    mainloop()
